/*! \brief Descrizione breve dell'Applicativo \n
 * 5 Rulli che girano
 * 
 * Descrizione dettagliata dell'Applicativo
 * Slot Machine
 */
 
#include <ClanLib/core.h>
#include <ClanLib/application.h>
#include <ClanLib/display.h>
#include <ClanLib/gl.h>

#include "Rullo.h"

/*! \file App.cpp
    \brief Documentazione define
    
    Questa è la documentazione dei define in App.cpp.
*/

/*!
  \def NUM_SIMBOLI
  Sono il numero dei diversi simboli della Slot.
*/

/*! 
   \def XRULLO
   E' la coordinata x da dove deve essere disegnato il primo rullo.
*/

#define NUM_SIMBOLI 12
#define XRULLO 45
#define YRULLO 45
#define VELOCITA_RULLO 40
#define STEPS_SCORRIMENTO_MIN 11
#define DELTA_STEPS_SCORRIMENTO 6

class MyApp : public CL_ClanApplication
{
public:
	virtual int main(int argc, char **argv)
	{
		// Create a console window for text-output if not available
		// Use printf or cout to display some text in your program
		CL_ConsoleWindow console("Console");
		console.redirect_stdio();

		try
		{
			// Initialize ClanLib base components
			CL_SetupCore setup_core;
			// Initialize the ClanLib display component
			CL_SetupDisplay setup_display;
			// Initialize the ClanLib GL component
			CL_SetupGL setup_gl;

			// Create a display window
			CL_DisplayWindow window("ClanLib application", 800, 600);

			// Creo slot per il segnale di chiusura finestra
			CL_Slot termina=window.sig_window_close().connect(this,&MyApp::Termina);

			// Creo slot per il segnale di pressione tasto tastiera
			CL_Slot slotKeyDown=CL_Keyboard::sig_key_down().connect(this, &MyApp::onKeyDown);

			// Funzione locale che inizializza tutte le variabili e i rulli
			Inizializzazione();
			
			// Run until someone presses escape
			while((!CL_Keyboard::get_keycode(CL_KEY_ESCAPE))&&(fine==false))
			{
				CL_Display::clear(CL_Color(0, 0, 0));

				rullo1->Update();
				rullo1->Disegna();
				rullo2->Update();
				rullo2->Disegna();
				rullo3->Update();
				rullo3->Disegna();
				rullo4->Update();
				rullo4->Disegna();
				rullo5->Update();
				rullo5->Disegna();

				// Flip the display (using a double-buffer),
				// showing on the screen what we have drawed
				// since last call to flip()
				CL_Display::flip();

				// This call updates input and performs other "housekeeping"
				// Call this each frame
				// Also, gives the CPU a rest for 10 milliseconds to catch up
				CL_System::keep_alive(1);
			}
		}
		// Catch any errors from ClanLib
		catch (CL_Error err)
		{
			// Display the error message
			std::cout << err.message.c_str() << std::endl;
		}

		// Display console close message and wait for a key
//		console.display_close_message();

		return 0;
	}
	void Inizializzazione()
	{
		// La variabile fine è utilizzata per far terminare il loop quando è TRUE
		fine=false;

		// Costruisco i 5 rulli che compongono il gioco
		rullo1=new Rullo;
		rullo2=new Rullo;
		rullo3=new Rullo;
		rullo4=new Rullo;
		rullo5=new Rullo;

		// Passo ai rulli il numero di simboli presenti nel gioco
		rullo1->num_simboli=NUM_SIMBOLI;
		rullo2->num_simboli=NUM_SIMBOLI;
		rullo3->num_simboli=NUM_SIMBOLI;
		rullo4->num_simboli=NUM_SIMBOLI;
		rullo5->num_simboli=NUM_SIMBOLI;

		// Calcolo tutte le x dei vari rulli
		xRullo1=XRULLO;
		deltaxRullo=rullo1->TornaDimOriz();
		xRullo2=xRullo1+deltaxRullo;
		xRullo3=xRullo2+deltaxRullo;
		xRullo4=xRullo3+deltaxRullo;
		xRullo5=xRullo4+deltaxRullo;

		// Passo ai rulli la coordinata x associata
		rullo1->xRullo=xRullo1;
		rullo2->xRullo=xRullo2;
		rullo3->xRullo=xRullo3;
		rullo4->xRullo=xRullo4;
		rullo5->xRullo=xRullo5;

		// Passo ai rulli la coordinata y associata
		yRullo=YRULLO;
		rullo1->yRullo=yRullo;
		rullo2->yRullo=yRullo;
		rullo3->yRullo=yRullo;
		rullo4->yRullo=yRullo;
		rullo5->yRullo=yRullo;

		// Creo un vettore di numeri che rappresentano gli step dei rulli
		int vettore[MAX_BUFFER];
		int num_step=MAX_BUFFER;
		for(int i=0, j=0;i<num_step;i++)
		{
			vettore[i]=j;
			if(j==11)
				j=0;
			else
				j++;
		}

		// Inizializzo i rulli passando il vettore e il numero di step che li caratterizza
		rullo1->Inizializza(vettore,num_step);
		rullo2->Inizializza(vettore,num_step);
		rullo3->Inizializza(vettore,num_step);
		rullo4->Inizializza(vettore,num_step);
		rullo5->Inizializza(vettore,num_step);
	}
	void Termina()
	{
		// La variabile fine è utilizzata per far terminare il loop quando è TRUE
		fine=true;
	}
	void onKeyDown(const CL_InputEvent &key)
	{
		// La funzione Scorri del rullo fa scorrere il rullo con la velocità, step da fare e step finale
		rullo1->Scorri(VELOCITA_RULLO,STEPS_SCORRIMENTO_MIN+(DELTA_STEPS_SCORRIMENTO*0),3);
		rullo2->Scorri(VELOCITA_RULLO,STEPS_SCORRIMENTO_MIN+(DELTA_STEPS_SCORRIMENTO*1),7);
		rullo3->Scorri(VELOCITA_RULLO,STEPS_SCORRIMENTO_MIN+(DELTA_STEPS_SCORRIMENTO*2),9);
		rullo4->Scorri(VELOCITA_RULLO,STEPS_SCORRIMENTO_MIN+(DELTA_STEPS_SCORRIMENTO*3),11);
		rullo5->Scorri(VELOCITA_RULLO,STEPS_SCORRIMENTO_MIN+(DELTA_STEPS_SCORRIMENTO*4),0);

	 }
public:
	CL_GraphicContext *gc;

	Rullo* rullo1;
	Rullo* rullo2;
	Rullo* rullo3;
	Rullo* rullo4;
	Rullo* rullo5;

	bool fine;

	int xRullo1;
	int xRullo2;
	int xRullo3;
	int xRullo4;
	int xRullo5;
	int deltaxRullo;
	int yRullo;
} app;
